<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ref, watch, onMounted, reactive } from 'vue'
import { TUser } from '@/Types/user'
import { getClassnameListService } from '@/api/education/classname'
import { Plus } from '@element-plus/icons-vue'
import type { FormInstance, FormRules } from 'element-plus'

// 初始化表单
const dialogRef = ref()
const formRef = ref<FormInstance>()
const formRef2 = ref<FormInstance>()
const uploadRef = ref()
const userDialogLoading = ref(false)
const form = ref<TUser>({
	account: '',
	password: '',
	uname: '',
	userTypeId: '',
	avatar: '' as string | File,
	classId: '',
	typeNumber: '',
	phoneNumber: ''
})

// 表单验证规则
const rules = reactive<FormRules>({
	account: [
		{ required: true, message: '请输入账号', trigger: 'blur' },
		{
			pattern: /^[a-zA-Z0-9]+$/,
			message: '账号只能包含英文和数字',
			trigger: 'blur'
		}
	],
	password: [
		{ required: true, message: '请输入密码', trigger: 'blur' },
		{ min: 6, message: '密码长度不能少于6个字符', trigger: 'blur' }
	],
	uname: [
		{ required: true, message: '请输入姓名', trigger: 'blur' },
		{
			pattern: /^[\u4e00-\u9fa5]+$/,
			message: '姓名只能是中文',
			trigger: 'blur'
		}
	],
	userTypeId: [{ required: true, message: '请选择用户类型', trigger: 'change' }],
	typeNumber: [
		{
			pattern: /^\d+$/,
			message: '学号只能是数字',
			trigger: 'blur'
		}
	]
})

// 班级列表
const classList = ref<ClassInfo[]>([])
// 选中的班级ID数组
const selectedClassIds = ref<number[]>([])
// 添加班级相关的类型
interface ClassInfo {
	classId: number
	level: string
	academy: string
	major: string
	grade: number
	classname: number
}
// 接收父组件数据
const props = defineProps<{
	dialogVisible: boolean
}>()

/**
 * 向父组件传递数据
 */
const emit = defineEmits(['closeDialog', 'setUserData'])
const closeDialog = () => {
	// 关闭弹窗时清除表单和图片数据
	clearFormData()
	emit('closeDialog', false)
	userDialogLoading.value = false
}
// 添加用户
const addUser = () => {
	// 验证左侧表单
	if (!formRef.value) return

	formRef.value.validate((valid1) => {
		// 验证右侧表单（如果存在且用户类型是学生）
		let valid2 = true
		if (form.value.userTypeId === '1' && formRef2.value) {
			formRef2.value.validate((valid) => {
				valid2 = valid
			})
		}

		// 只有当两个表单都验证通过才继续
		if (valid1 && valid2) {
			// 学生必须选择班级
			if (form.value.userTypeId === '1' && !form.value.classId) {
				ElMessage.error('请为学生选择班级')
				return
			}

			// file数据需要fd格式传递
			const fileData = new FormData()

			// 获取用户信息
			const userData = {
				...form.value,
				avatar: '',
				classId:
					typeof form.value.classId === 'string'
						? form.value.classId.split(',').map(Number)
						: form.value.classId
			}

			// 获取头像信息
			if (form.value.avatar != undefined) {
				fileData.append('file', form.value.avatar)
				fileData.append('fileType', 'avatar')
			}

			emit('setUserData', { userData, fileData })
		} else {
			ElMessage.error('请正确填写表单内容')
		}
	})
}

/**
 * 头像上传
 */
interface TFile {
	raw: File
}
// 添加图片预览相关的响应式变量和方法
const imageUrl = ref('')
// 处理图片选择
const avatarChange = (file: TFile) => {
	// 清除之前的上传文件
	if (uploadRef.value) {
		uploadRef.value.clearFiles()
	}

	const fileType = file.raw.type === 'image/jpeg' || file.raw.type === 'image/png'
	const fileSize = file.raw.size / 1024 / 1024 < 3
	if (!fileType || !fileSize) {
		ElMessage.error('上传头像图片只能是 JPG/PNG 格式，且大小不能超过 3MB!')
		return
	}

	// 先清除旧预览URL（如果存在）
	if (imageUrl.value) {
		URL.revokeObjectURL(imageUrl.value)
	}

	// 创建新预览URL并设置图片
	imageUrl.value = URL.createObjectURL(file.raw)
	form.value.avatar = file.raw
}

/**
 * 弹窗控制
 */
const clearFormData = () => {
	if (formRef.value) {
		formRef.value.resetFields()
	}
	if (uploadRef.value) {
		uploadRef.value.clearFiles()
	}
	// 清除图片预览
	imageUrl.value = ''
	form.value.avatar = '' as string | File
}
const openUserDialogLoading = () => {
	userDialogLoading.value = true
}
const closeUserDialogLoading = () => {
	userDialogLoading.value = false
}

/**
 * 数据处理
 */
// 获取班级列表并排序
const getClassList = async () => {
	try {
		const res = await getClassnameListService()
		if (res.data.code === 1) {
			// 对班级列表进行排序
			classList.value = res.data.data.sort((a: ClassInfo, b: ClassInfo) => {
				// 1. 按学历层次排序（本科在前，专科在后）
				if (a.level !== b.level) {
					return a.level === 'undergrad' ? -1 : 1
				}
				// 2. 按学院名称排序
				if (a.academy !== b.academy) {
					return a.academy.localeCompare(b.academy)
				}
				// 3. 按专业排序
				if (a.major !== b.major) {
					return a.major.localeCompare(b.major)
				}
				// 4. 按年级从小到大排序
				if (a.grade !== b.grade) {
					return a.grade - b.grade
				}
				// 5. 按班级号从小到大排序
				return a.classname - b.classname
			})
		}
	} catch (error) {
		ElMessage.error('获取班级列表失败')
	}
}
// 格式化班级显示文本
const formatClassLabel = (classInfo: ClassInfo) => {
	if (!classInfo) return ''
	const levelText = classInfo.level === 'undergrad' ? '本科' : '专科'
	return `${levelText}-${classInfo.academy}-${classInfo.major}-${classInfo.grade}级-${classInfo.classname}班`
}
// 处理班级选择变化
const handleClassChange = (val: number | number[]) => {
	// 统一使用数组存储
	if (Array.isArray(val)) {
		form.value.classId = val.join(',')
	} else {
		form.value.classId = String(val)
		selectedClassIds.value = [val] // 将单选也转换为数组
	}
}
// 监听用户类型变化
watch(
	() => form.value.userTypeId,
	() => {
		selectedClassIds.value = [] // 清空已选班级
		form.value.classId = '' // 清空表单中的班级ID
	}
)
// 弹窗组件中添加watch监听对话框可见状态
watch(
	() => props.dialogVisible,
	(newVal) => {
		if (!newVal) {
			// 弹窗关闭时，确保清除所有数据
			clearFormData()
			userDialogLoading.value = false
		}
	}
)

/**
 * 数据获取
 */
onMounted(() => {
	getClassList()
})

/**
 * 方法处理
 */
defineExpose({
	clearFormData,
	openUserDialogLoading,
	closeUserDialogLoading
})
</script>

<template>
	<el-dialog
		ref="dialogRef"
		v-model="props.dialogVisible"
		@close="closeDialog"
		title="添加用户"
		width="800"
	>
		<div class="dialog-content" v-loading="userDialogLoading">
			<!-- 左侧 -->
			<el-form
				ref="formRef"
				:model="form"
				:rules="rules"
				class="form-container"
				label-position="right"
			>
				<el-form-item prop="account" label="账号" label-width="100px">
					<el-input v-model="form.account" autocomplete="off" placeholder="请输入英文和数字" />
				</el-form-item>
				<el-form-item prop="password" label="密码" label-width="100px">
					<el-input
						v-model="form.password"
						type="password"
						autocomplete="off"
						placeholder="请输入密码"
					/>
				</el-form-item>
				<el-form-item prop="uname" label="姓名" label-width="100px">
					<el-input v-model="form.uname" autocomplete="off" placeholder="请输入中文姓名" />
				</el-form-item>
				<el-form-item prop="phoneNumber" label="联系方式" label-width="100px">
					<el-input v-model="form.phoneNumber" autocomplete="off" placeholder="请输入联系方式" />
				</el-form-item>
				<el-form-item prop="userTypeId" label="用户类型" label-width="100px">
					<el-select v-model="form.userTypeId" placeholder="请选择用户类型">
						<el-option label="学生" value="1" />
						<el-option label="任课老师" value="2" />
						<el-option label="辅导员" value="3" />
						<el-option label="管理员" value="4" />
					</el-select>
				</el-form-item>
				<el-form-item prop="avatar" label="头像" label-width="100px">
					<el-upload
						ref="uploadRef"
						class="avatar-uploader"
						:limit="1"
						:accept="['image/jpeg', 'image/png']"
						title="仅支持上传3MB以内的JPG/PNG格式图片"
						:auto-upload="false"
						:show-file-list="false"
						:on-change="avatarChange"
					>
						<img v-if="imageUrl" :src="imageUrl" class="avatar" />
						<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
					</el-upload>
				</el-form-item>
			</el-form>

			<!-- 右侧 -->
			<el-form
				ref="formRef2"
				class="form-container"
				v-if="form.userTypeId"
				:model="form"
				:rules="rules"
				label-position="right"
			>
				<el-form-item prop="classId" label="班级" label-width="100px">
					<el-select
						v-model="selectedClassIds"
						:multiple="form.userTypeId !== '1'"
						:multiple-limit="form.userTypeId === '1' ? 1 : undefined"
						:filterable="true"
						placeholder="请选择班级"
						@change="handleClassChange"
						style="width: 100%"
						collapse-tags
						collapse-tags-tooltip
					>
						<el-option
							v-for="item in classList"
							:key="item.classId"
							:label="formatClassLabel(item)"
							:value="item.classId"
						/>
					</el-select>

					<!-- 已选班级展示区域 -->
					<div class="selected-classes" v-if="selectedClassIds.length > 0">
						<el-tag v-for="classId in selectedClassIds" :key="classId" class="class-tag">
							{{ formatClassLabel(classList.find((c) => c.classId === classId) as ClassInfo) }}
						</el-tag>
					</div>
				</el-form-item>

				<!-- 学生学号输入框 -->
				<el-form-item
					v-if="form.userTypeId === '1'"
					prop="typeNumber"
					label="学号"
					label-width="100px"
				>
					<el-input v-model="form.typeNumber" autocomplete="off" placeholder="请输入数字学号" />
				</el-form-item>
			</el-form>
		</div>

		<template #footer>
			<div class="dialog-footer">
				<el-button @click="closeDialog">取消</el-button>
				<el-button type="primary" @click="addUser">添加</el-button>
			</div>
		</template>
	</el-dialog>
</template>

<style lang="scss" scoped>
.dialog-content {
	display: flex;
	justify-content: space-between;
	gap: 20px;
	padding: 0 20px;

	.form-container {
		flex: 1;
		max-width: 50%;

		:deep(.el-form-item) {
			margin-bottom: 20px;

			.el-input,
			.el-select {
				width: 100%;
			}
		}
	}
}

.el-upload {
	width: 100%;
	text-align: left;
}

.avatar-uploader {
	:deep(.el-upload) {
		border: 1px dashed var(--el-border-color);
		border-radius: 6px;
		cursor: pointer;
		position: relative;
		overflow: hidden;
		transition: var(--el-transition-duration-fast);

		&:hover {
			border-color: var(--el-color-primary);
		}
	}
}

.avatar-uploader-icon {
	font-size: 28px;
	color: #8c939d;
	width: 178px;
	height: 178px;
	text-align: center;
	line-height: 178px;
}

.avatar {
	width: 178px;
	height: 178px;
	display: block;
	object-fit: cover;
}

.selected-classes {
	margin-top: 10px;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;

	.class-tag {
		margin-right: 8px;
		margin-bottom: 8px;
	}
}

.class-option {
	display: block;
	padding: 5px 0;
}

:deep(.el-select-dropdown__item) {
	padding: 0 12px;
}
</style>
